/*
 * Copyright (c) 2022. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package com.tarry.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Slf4j
@Service
public class RetryService {

    private Long lastTime = 0L;

    /**
     * 默认重试,可以看到会执行3次,每次间隔1000ms
     */
    @Retryable
    public void test1(){
        nothingToDo("test1");
    }

    private void nothingToDo(String name) {
        long now = System.currentTimeMillis();
        if (lastTime != 0L){
            log.info("distance:{}ms",now - lastTime);
        }
        log.info("{}: try do something",name);
        lastTime = now;
        throw new RuntimeException("call error");
    }

    /**
     * 可以发现并不会重试
     */
    @Retryable(maxAttempts = 4,value = {IOException.class})
    public void test2(){
        nothingToDo("test2");
    }

    /**
     * 最小1000,最大10000,随机1000-10000之间延迟
     */
    @Retryable(maxAttempts = 7,include = {RuntimeException.class}, backoff = @Backoff(delay = 1000,maxDelay = 10000))
    public void test3(){
        nothingToDo("test3");
    }

    /**
     * 首次延迟1秒,后续为当前延迟*1.5
     */
    @Retryable( maxAttempts = 5,include = {RuntimeException.class}, backoff = @Backoff(delay = 1000,multiplier = 1.5,random = true))
    public void test4(){
        nothingToDo("test4");
    }

    @Retryable
    public void test5(int num){
        nothingToDo("test5");
    }

    @Retryable(maxAttempts = 5,
            backoff= @Backoff(value = 1500, maxDelay = 100000, multiplier = 3))
    public void test6(){
        nothingToDo("test6");
    }


    @Recover
    public void recover(){
        log.info("recover: >>>>>>>>>>>>>>>>>>>>>");
    }


}
